#include <iostream>
#include <arpa/inet.h>
#include <netinet/in.h>

#include <qbytearray.h>
#include <tws_debugging.h>
#include <xinifile.h>
#include "xinfomatiptypeparser.h"

const char DEFAULT_DEVICE[] = "eth0";
const char DEFAULT_INI_FILE[] = "/usr/infomat/udpd.conf";

//#define _DEBUGING_IP_

XInfomatIpTypeParser::XInfomatIpTypeParser() :
    m_result(INFOMAT_RESULT_OK)
{
	DEBUG("Ip Type Constructor");
	memset (&m_ipType, 0x00, sizeof(m_ipType));
}

XInfomatIpTypeParser::~XInfomatIpTypeParser()
{
}

void XInfomatIpTypeParser::read()
{
    XIniFile iniFile;
    char cur_address[64] ;
    char cur_gateway[64]  ;

    assert(0 == iniFile.open(DEFAULT_INI_FILE));

    if (0 != iniFile.readString("", "IPV4ADDRESS", cur_address, 64))
        m_result = INFOMAT_RESULT_ERR;

    if (0 != iniFile.readString("", "GATEWAY", cur_gateway, 64))
        m_result = INFOMAT_RESULT_ERR;

    iniFile.close();

    uint32_t uIp = 0;
    inet_pton(AF_INET, cur_address, &uIp);

    uint32_t uGateway = 0;
    inet_pton(AF_INET, cur_gateway, &uGateway);

    m_ipType.ip = uIp;
    m_ipType.gateway = uGateway;
    
	return;
}

void XInfomatIpTypeParser::write()
{
    XIniFile iniFile;
    char strIp[64] = "0";
    inet_ntop(AF_INET, &(m_ipType.ip), strIp, 64);
    char strGateway[64] = "0";
    inet_ntop(AF_INET, &(m_ipType.gateway), strGateway, 64);

    assert(0 == iniFile.open(DEFAULT_INI_FILE, EIniReadWrite));

    if (0 != iniFile.writeString("", "IPV4ADDRESS", strIp))
    {
        DEBUG("saving ip failed");
        m_result = INFOMAT_RESULT_ERR;
    }

    if (0 != iniFile.writeString("", "GATEWAY", strGateway))
    {
        DEBUG("saving gateway failed");
        m_result = INFOMAT_RESULT_ERR;
    }

    iniFile.flush();
    return;
}

void XInfomatIpTypeParser::getResource(QByteArray in_datagram)
{
    char* data = new char[in_datagram.size()];
    memcpy(data, in_datagram.data(), in_datagram.size());

	STInfomatIpType * tmpStIpType = reinterpret_cast<STInfomatIpType*> (data);
	memcpy (&m_ipType, tmpStIpType, sizeof(m_ipType));
	tmpStIpType = NULL;
#ifdef _DEBUGING_IP_
    DEBUG("protocol : %x", m_ipType.head.protocol);
    DEBUG("type     : %d", m_ipType.head.type);
    DEBUG("size     : %d", m_ipType.head.size);
    DEBUG("result   : %d", m_ipType.head.result);
    DEBUG("command  : %d", m_ipType.head.command);
    DEBUG("ip       : %d", m_ipType.ip);
    DEBUG("gateway  : %d", m_ipType.gateway);
    DEBUG("netmask  : %d", m_ipType.netmask);
#endif
    assert(INFOMAT_CONFIG_PROTOCOL == *data);
    m_ipType.head.result = INFOMAT_RESULT_OK; //initialized

    switch (m_ipType.head.command)
    {
        case INFOMAT_COMMAND_READ:
            read();
            break;

        case INFOMAT_COMMAND_WRITE:
            write();
            break;

        default:
            DEBUG("XIpTypeParser: no such command");
            m_result = INFOMAT_RESULT_ERR;
            break;
    }

	/* *** clean up  *** */
	if (NULL != data)
	{
		delete [] data;
		data = NULL;
	}
    return;
}

QByteArray XInfomatIpTypeParser::getOutDatagram()
{
    m_ipType.head.result = m_result;
    char* data = reinterpret_cast<char*> (&m_ipType);
    QByteArray outdata = QByteArray(data, sizeof(m_ipType));

#ifdef _DEBUGING_IP_
	DEBUG("IpType: Send out data checking....");
	for (int i=0; i<outdata.size();++i)
	{
		DEBUG("Bytes:%02x",*(outdata.data()+i));
	}
#endif
	return outdata;
}
